#ifndef _MDrawContext
#define _MDrawContext
//-
// ==========================================================================
// Copyright (C) 2010 Autodesk, Inc., and/or its licensors.  All
// rights reserved.
//
// The coded instructions, statements, computer programs, and/or related
// material (collectively the "Data") in these files contain unpublished
// information proprietary to Autodesk, Inc. ("Autodesk") and/or its
// licensors,  which is protected by U.S. and Canadian federal copyright law
// and by international treaties.
//
// The Data may not be disclosed or distributed to third parties or be
// copied or duplicated, in whole or in part, without the prior written
// consent of Autodesk.
//
// The copyright notices in the Software and this entire statement,
// including the above license grant, this restriction and the following
// disclaimer, must be included in all copies of the Software, in whole
// or in part, and all derivative works of the Software, unless such copies
// or derivative works are solely in the form of machine-executable object
// code generated by a source language processor.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
// AUTODESK DOES NOT MAKE AND HEREBY DISCLAIMS ANY EXPRESS OR IMPLIED
// WARRANTIES INCLUDING, BUT NOT LIMITED TO, THE WARRANTIES OF
// NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE,
// OR ARISING FROM A COURSE OF DEALING, USAGE, OR TRADE PRACTICE. IN NO
// EVENT WILL AUTODESK AND/OR ITS LICENSORS BE LIABLE FOR ANY LOST
// REVENUES, DATA, OR PROFITS, OR SPECIAL, DIRECT, INDIRECT, OR
// CONSEQUENTIAL DAMAGES, EVEN IF AUTODESK AND/OR ITS LICENSORS HAS
// BEEN ADVISED OF THE POSSIBILITY OR PROBABILITY OF SUCH DAMAGES.
// ==========================================================================
//+
//
// CLASS:    MDrawContext
//
// ****************************************************************************
//
// CLASS DESCRIPTION (MDrawContext)
//
//  MDrawContext allows access to hardware draw context information
//
// ****************************************************************************

#if defined __cplusplus

// ****************************************************************************
// INCLUDED HEADER FILES

#include <maya/MStatus.h>
#include <maya/MMatrix.h>
#include <maya/MDoubleArray.h>
#include <maya/MFloatPoint.h>
#include <maya/MFloatVector.h>
#include <maya/MColor.h>
#include <maya/MBoundingBox.h>
#include <maya/MHWGeometry.h>

// ****************************************************************************
// NAMESPACE

namespace MHWRender
{

// ****************************************************************************
// DECLARATIONS

class MStateManager;

// ****************************************************************************
// CLASS DECLARATION (MDrawContext)

//! \ingroup OpenMayaRender
//! \brief Class to allow access to hardware draw context information.
/*!
MDrawContext provides access to current hardware draw context information
when drawing is performed in either MPxShaderOverride or MPxDrawOverride.

MDrawContext is read-only and cannot be instantiated by the plugin writer.

The information provided includes various transformation matrices,
camera information, and render target information such as output buffer
size. It is also possible to access and alter GPU state through this calss.

There are a few main advantages for using this class:

1. The data is computed and cached as required. This can avoid work for the
plugin writer to extract this information themselves.
2. The plugin writer should not need to directly access the device to extract
this information. Any data extraction from the device has a performance
penalty which can be avoided.
3. The information is device aware, meaning that it will return the correct
results based on the current active device. For example it will return the
appropriate values for DirectX versus an OpenGL device.

Some information will vary from one draw to the next draw such as the
object-to-world matrix which will change as different objects are being drawn.
*/
class OPENMAYARENDER_EXPORT MDrawContext
{
public:
	//! Matrices that can be accessed
	enum MatrixType {
		kWorldMtx,                      //!< Object to world matrix
		kWorldTransposeMtx,             //!< Object to world matrix transpose
		kWorldInverseMtx,               //!< Object to world matrix inverse
		kWorldTranspInverseMtx,         //!< Object to world matrix transpose inverse (adjoint)
		kViewMtx,                       //!< World to view matrix
		kViewTransposeMtx,              //!< World to view matrix tranpose
		kViewInverseMtx,                //!< World to view matrix inverse
		kViewTranspInverseMtx,          //!< World to view matrix transpose inverse (adjoint)
		kProjectionMtx,                 //!< Projection matrix
		kProjectionTranposeMtx,         //!< Projection matrix tranpose
		kProjectionInverseMtx,          //!< Projection matrix inverse
		kProjectionTranspInverseMtx,    //!< Projection matrix tranpose inverse (adjoint)
		kViewProjMtx,                   //!< View * projection matrix
		kViewProjTranposeMtx,           //!< View * projection matrix tranpose
		kViewProjInverseMtx,            //!< View * projection matrix inverse
		kViewProjTranspInverseMtx,      //!< View * projection matrix tranpose inverse (adjoint)
		kWorldViewMtx,                  //!< World * view matrix
		kWorldViewTransposeMtx,         //!< World * view matrix transpose
		kWorldViewInverseMtx,           //!< World * view matrix inverse
		kWorldViewTranspInverseMtx,     //!< World * view matrix transpose inverse (adjoint)
		kWorldViewProjMtx,              //!< World * view * projection matrix
		kWorldViewProjTransposeMtx,     //!< World * view * projection matrix transpose
		kWorldViewProjInverseMtx,       //!< World * view * projection matrix inverse
		kWorldViewProjTranspInverseMtx  //!< World * view * projection matrix tranpose inverse (adjoint)
	};
	MMatrix getMatrix( MDrawContext::MatrixType mtype, MStatus* ReturnStatus=NULL ) const;

	//! Vectors or positions that can be accessed
	enum TupleType {
		kViewPosition,		//!< View position
		kViewDirection,		//!< View direction
		kViewUp,			//!< View up vector
		kViewRight,			//!< View right vector
	};
	MDoubleArray getTuple( MDrawContext::TupleType ttype, MStatus* ReturnStatus=NULL ) const;

	MBoundingBox getSceneBox(MStatus* ReturnStatus=NULL) const;

	MStatus getViewportDimensions( int &originX, int &originY, int &width, int &height) const;
	MStatus getRenderTargetSize( int &width, int &height) const;
	MStatus getDepthRange( float &nearVal, float &farVal ) const;
	bool viewDirectionAlongNegZ( MStatus* ReturnStatus ) const;

	unsigned int numberOfActiveLights(MStatus* ReturnStatus=NULL) const;
	MStatus getLightInformation( unsigned int lightNumber,
								 MFloatPoint &position, MFloatVector &direction,
								 float &intensity, MColor &color, bool &hasDirection,
								 bool &hasPosition ) const;

	//! Display style
    enum DisplayStyle {
        kGouraudShaded = 0x1,		//!< Gouraud shaded display.
        kWireFrame = 0x2,			//!< Wire frame display.
    };
	int getDisplayStyle() const;

	MHWRender::MStateManager* getStateManager() const;

	static const char* className();

private:
	MDrawContext();
	~MDrawContext();

	void setData(void* data);
	void* fData;
	MStateManager* fStateManager;

	friend class MRenderItem;

public:
	//	Required to work around a bug in swig.
	void _swigForceParamType(MDoubleArray) {}

};     /* draw context */

} // namespace MHWRender

#endif /* __cplusplus */
#endif /* _MDrawContext */
